'use client';

import {
  type ChangeEvent,
  type FormEvent,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { updatePostTemplate } from '@/services/api';
import diff from 'microdiff';
import type { IDifference, IPostTemplate } from '@/interfaces';
import type { TBody } from '@/types';
import useToast from '@/hooks/useToast';
import { getDiffData, getFilterData } from '@/lib/tool';
import { PostTemplateAdminContext } from '@/contexts/admin/forum/postTemplate';
import classNames from 'classnames';
import useContentLayer from '@/hooks/useContentLayer';
import Editor from '@/app/[locale]/editor/wrapper';

export default function UpdatePostTemplateContent({
  details,
}: {
  details: IPostTemplate;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    content?: string;
  }>({
    content: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const queryClient = useQueryClient();
  const context = useContext(PostTemplateAdminContext);
  const metadata = context.metadata!;
  const editorContextRef = useRef<{
    context: any;
    getEditorContent: () => string;
  }>({
    context: undefined,
    getEditorContent: () => '',
  });
  const [isPreview, setIsPreview] = useState(false);
  const [previewContent, setPreviewContent] = useState('');

  useContentLayer({
    dep: previewContent,
    metadata,
  });

  const updatePostTemplateMutation = useMutation(
    async (
      variables: TBody<{
        name?: string;
        overview?: string;
        content?: string;
        sort?: number;
        sectionId?: number;
      }>,
    ) => {
      await updatePostTemplate(variables);
      await queryClient.invalidateQueries(['/forum', '/templates', details.id]);
    },
  );

  useEffect(() => {
    if (details) {
      setForm({
        content: details.content,
      });
    }
  }, [details]);
  useEffect(() => {
    if (details) {
      const differences = diff(
        {
          content: details.content,
        },
        {
          content: form.content,
        },
      );
      setDifferenceData(differences);
    }
  }, [form, details]);

  function onChangeForm(e: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
    const name = e.target.name;
    const value = e.target.value;
    setForm({ ...form, [name]: value });
  }

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();
      const body = getFilterData(getDiffData(differenceData));
      body.content = getEditorContent();

      await updatePostTemplateMutation.mutateAsync({
        id: details.id,
        data: {
          content: body.content,
        },
      });

      clearData();
      show({
        type: 'SUCCESS',
        message: '保存完成',
      });
    } catch (e) {
      updatePostTemplateMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickPreview() {
    setPreviewContent(getEditorContent());
    setIsPreview(!isPreview);
  }

  function checkForm() {
    if (!getEditorContent()) {
      throw '帖子模板内容不能为空';
    }
  }

  function getEditorContent() {
    return editorContextRef.current.getEditorContent();
  }

  function clearData() {
    setDifferenceData([]);
  }

  return (
    <div className="row">
      <div className="col">
        <form onSubmit={onClickSave} className="vstack gap-4">
          <div className={classNames(isPreview ? 'd-none' : 'd-block')}>
            <label className="form-label">内容</label>
            <Editor
              id={details.section.id}
              initialData={details.content}
              metadata={metadata}
              type="postTemplate"
              ref={editorContextRef}
            />
          </div>

          <div className={classNames(isPreview ? 'd-block' : 'd-none')}>
            {previewContent ? (
              <div
                className="clearfix text-break content-layer"
                dangerouslySetInnerHTML={{ __html: previewContent }}
              />
            ) : (
              <div className="text-muted">暂无预览内容</div>
            )}
          </div>

          <div className="hstack gap-4">
            <button
              type="submit"
              disabled={updatePostTemplateMutation.isLoading}
              className="btn btn-success w-25 my-4"
            >
              {updatePostTemplateMutation.isLoading && (
                <span
                  className="spinner-border spinner-border-sm me-2"
                  role="status"
                  aria-hidden="true"
                ></span>
              )}
              更新
            </button>

            <button
              onClick={onClickPreview}
              type="button"
              className={classNames(
                'btn w-25 my-4',
                isPreview ? 'btn-secondary' : 'btn-light',
              )}
            >
              {isPreview ? '返回' : '预览'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
